package com.blueflamedev.util
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	/**
	 * The Framerate Monitor simply exposes a value <code>fps</code> that tells you the current actual frames per second
	 * of the flash movie. After passing the stage in as an argument, you can start and stop the monitoring process with
	 * <code>start()</code> and <code>stop()</code>.
	 * 
	 * @author Eric Smith
	 */	
	public class FramerateMonitor extends EventDispatcher
	{
		/**
		 * @private 
		 */		
		private var _stage:Stage;
		
		/**
		 * @private 
		 */		
		private var _count:int;
		
		/**
		 * @private 
		 */	
		private var _fps:Number;
		
		/**
		 * @private 
		 */	
		private var _timer:Timer;
		
		/**
		 * @private 
		 */	
		private var _isRunning:Boolean;
		
		/**
		 * The constructor. Start this when your movie starts.
		 * 
		 * @param stage The main stage
		 */		
		public function FramerateMonitor(stage:Stage)
		{
			_stage = stage;
			_count = 0;
			_timer = new Timer(1000);
			_timer.addEventListener(TimerEvent.TIMER, onTimer);
			_fps = -1;
		}
		
		/**
		 * Returns the frames per second.
		 */		
		public function get fps():Number
		{
			return _fps;
		}
		
		/**
		 * starts monitoring the frames per second
		 */		
		public function start():void
		{
			if (!_isRunning)
			{
				_isRunning = true;
				_fps = 0;
				_count = 0;
				_timer.start();
				_stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
			}	
		}
		
		/**
		 * Stops monitoring the frames per second. Tracing <code>fps</code> will result in -1;
		 */		
		public function stop():void
		{
			if (_isRunning)
			{
				_isRunning = false;
				_timer.stop();
				_timer.reset();
				_fps = -1;
				_count = 0;
				_stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
		}
		
		/**
		 * @private 
		 */	
		private function onTimer(event:TimerEvent):void
		{
			_fps = _count;
			_count = 0;
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		/**
		 * @private
		 */		
		private function onEnterFrame(event:Event):void
		{
			_count++;
		}
	}
}